﻿using System.Linq;
using Microsoft.WowAddonStudio.FrameXml.Serialization;
using Microsoft.WowAddonStudio.FrameXml.Serialization.Enumerations;
using Microsoft.WowAddonStudio.FrameXml.Serialization.LayoutFrames;
using Microsoft.WowAddonStudio.FrameXml.Serialization.Support;

using NUnit.Framework;

namespace Microsoft.WowAddonStudio.FrameXml.Serialization.Tests
{
    [TestFixture]
    public class LayeredLayoutFrameTest
    {
        [Test]
        public void DrawLayerTest()
        {
            var artworkList = new LayeredLayoutFrameList(new Layer { Level = DrawLayer.Artwork });
            var overlayList = new LayeredLayoutFrameList(new Layer { Level = DrawLayer.Overlay });

            var texture = new Texture();
            var fontString = new FontString();

            // Assert the default draw layers
            Assert.AreEqual(DrawLayer.Artwork, texture.DrawLayer);
            Assert.AreEqual(DrawLayer.Overlay, fontString.DrawLayer);

            // Add them to other layers
            artworkList.Add(fontString);
            overlayList.Add(texture);

            // Assert the updated draw layers
            Assert.AreEqual(DrawLayer.Artwork, fontString.DrawLayer);
            Assert.AreEqual(DrawLayer.Overlay, texture.DrawLayer);
        }

        [Test]
        public void FrameLayerTest()
        {
            var frame = new Frame();

            var texture = new Texture { ParentFrame = frame };
            var fontString = new FontString { ParentFrame = frame };

            // Assert the default draw layers
            Assert.AreEqual(DrawLayer.Artwork, texture.DrawLayer);
            Assert.AreEqual(DrawLayer.Overlay, fontString.DrawLayer);

            // Add the texture and the fontstring to the frame
            ((ISerializationObjectContainer)frame).Add(texture);
            ((ISerializationObjectContainer)frame).Add(fontString);

            // Assert that there are two layers
            Assert.AreEqual(2, frame.Layers.Count);

            // Assert that there is one layout frame in both Artwork and Overlay layers
            Assert.AreEqual(1, frame.Layers.Single(layer => layer.Level == DrawLayer.Artwork).Items.Count());
            Assert.AreEqual(1, frame.Layers.Single(layer => layer.Level == DrawLayer.Overlay).Items.Count());

            // Move the fontstring to the Artwork layer
            fontString.DrawLayer = DrawLayer.Artwork;

            // Assert that there is a single layer and has two layout frames
            Assert.AreEqual(1, frame.Layers.Count);
            Assert.AreEqual(2, frame.Layers.Single(layer => layer.Level == DrawLayer.Artwork).Items.Count());
        }

        [Test]
        public void LayerInheritanceTest()
        {
            // Create master frame and textures
            var masterFrame = new Frame();

            var masterArtworkTexture = new Texture { DrawLayer = DrawLayer.Artwork, ParentFrame = masterFrame };
            var masterOverlayTexture = new Texture { DrawLayer = DrawLayer.Overlay, ParentFrame = masterFrame };

            // Add the master textures
            ((ISerializationObjectContainer)masterFrame).Add(masterArtworkTexture);
            ((ISerializationObjectContainer)masterFrame).Add(masterOverlayTexture);

            // Create child frame and textures
            var childFrame = new Frame();

            var childArtworkTexture = new Texture { DrawLayer = DrawLayer.Artwork, ParentFrame = childFrame };

            // Add child texture
            ((ISerializationObjectContainer)childFrame).Add(childArtworkTexture);

            // Inherit from the master frame
            childFrame.InheritedObject = masterFrame;
            
            // Assert that there are two layers, Overlay with one texture, artwork with two textures
            Assert.AreEqual(2, childFrame.Layers.Count);

            Assert.AreEqual(1, childFrame.Layers.Single(layer => layer.Level == DrawLayer.Overlay).Items.Count);
            Assert.AreEqual(2, childFrame.Layers.Single(layer => layer.Level == DrawLayer.Artwork).Items.Count);

            // Move the master overlay texture to the artwork layer
            masterOverlayTexture.DrawLayer = DrawLayer.Artwork;

            // Assert that there is a single layer with three textures (Artwork)
            Assert.AreEqual(1, childFrame.Layers.Count);
            Assert.AreEqual(3, childFrame.Layers.Single(layer => layer.Level == DrawLayer.Artwork).Items.Count);
        }
    }
}
